const path = require("path");

const htmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebPackPlugin = require("clean-webpack-plugin");
const webpack = require("webpack");
module.exports = {
  // webpack --watch
  // watch: true // 当文件改变是自动打包

  // 比webpack --watch 功能更强,并且模拟了服务器的功能,
  // devserver 打包后的代码再内存中,从而提升打包速度
  // 如果代码改了后 会从新打包 重新刷新浏览器,我尽心页面交互后的显示效果消失了
  // hot:true,设置了就不会了
  devServer: {
    // contentBase: "./dist", // 指定哪个目录下的文件,
    open: true,
    hot: true, // 代码出错,修改正确后浏览器会重新刷新
    hotOnly: true, // 代码出错,修改正确后浏览器也不自动刷新,帮助一些操作复杂交互的复现(因为一刷新如果没有这个配置那么之前的交互全白写了)
    // Proxy: {
    //   //  changeOrigin: true // true: 浏览器调试工具显示的 是代理后的地址而不是本地服务的地址
    // },
  },

  entry: {
    main1: "./src/index.js",
    // main2: "./src/index.js",
  },
  output: {
    path: path.resolve(__dirname, "./dist"),

    // 打包输出的多个文件都会被插入到html文件中

    // filename: "build.js", // 不写就是 上面入口 的mian1 + .js => main1.js  main1.js main2.js
    // 额外配置
    filename: "[name].js", // 和 不写效果一样  main1.js main2.js

    /*
        需求:
            将打包后的index.html文件 给后端
            打包后的js文件 上传到cdn

            让后index.html引入将打包的js文件带一个cdn的域名,可以在output配置 https://cdn.com/main1.js

    */
    // 打包后的文件给后端
    // publicPath: "https://cdn.example.com/assets/",

    // script src="main.js"
    // ->
    // script src="/main.js"
    // publicPath: "/",
  },

  module: {
    rules: [
      {
        test: /\.jpg$/,
        use: {
          loader: "file-loader",
          options: {
            name: "[name]_[hash:5].[ext]",
          },
        },
      },
      {
        test: /\.(eot|ttf|svg)$/,
        use: {
          loader: "file-loader",
        },
      },

      {
        test: /\.(scss|css)$/,
        use: [
          {
            loader: "style-loader", // 将css 文件插入到 html模板head中
          },
          {
            loader: "css-loader", // 解决 css import 语法的解析
            options: {
              importLoaders: 2, // 保证 引入scss 文件都会依次从下到上执行所有的loader
              modules: true, // css 模块化打包 局部作用域的css
            },
          },
          {
            loader: "sass-loader",
          },
          {
            loader: "postcss-loader",
          },
        ],
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          //  下面设置可以zai .babelrc 中配置,下面直接不用写了
          // options: {
          // // 将es6 -> es5
          // presets: [
          //   [
          //     "@babel/preset-env",
          //     // polyfill 补充低版本没有的prosmise等 es6 api
          //     // 按需补充 polyfill
          //     {
          //       useBuiltIns: "usage",
          //       targets: {
          //         chrome: "67",
          //       },
          //     },
          //   ],
          // ],

          //   // 开发第三方插件组件 包时使用这种方式
          //   plugins: [
          //     [
          //       "@babel/plugin-transform-runtime", // 闭包的形式引入 polyfill 不会全局污染
          //       {
          //         corejs: 2, //  @babel/runtime-corejs2
          //         helpers: true,
          //         regenerator: true,
          //         useESModules: false,
          //       },
          //     ],
          //   ],
          // },
        },
      },
    ],
  },

  mode: "development",
  // cheap 只显示行 并且是业务代码
  //  moduel 显示业务代码
  // eval 精简 map
  // source-map 外面生成map 文件
  // inline  里面生成map文件

  // devtool 重新赋值none 就是 关闭sourcemap,
  // devtool: "none",
  // devtool: "source-map", // map文件在单独的文件
  // devtool: "inline-source-map", // map文件放在打包后的文件里面

  // devtool: "cheap-inline-source-map", // 和上面类似但是会省略列只显示行,并且 只会关业务代码,引入的node_modules不会显示

  // devtool: "cheap-module-inline-source-map", // 和上面类似但是会省略列只显示行,并且 会关业务代码,引入的node_modules也会显示

  devtool: "eval", // eval map字符串会议eval执行并且指向了 源代码对应的文件是哪个,最快,但是业务代码量大的话就没有那么友好

  /*  推荐 */
  // 开发环境推荐
  devtool: "cheap-module-eval-source-map",

  // 线上如果要报错 推荐
  // devtool: "cheap-module-source-map",

  // plugins 可以在webpack运行到某个时刻要执行的一些事情，类似于vue 的生命周期
  plugins: [
    // htmlwebpackplugin 会在打包结束后，自动生成一个html文件，并把打包生成的js自动引入到html文件
    new htmlWebpackPlugin({
      template: "./src/index.html",
    }),
    //  打包前删除之前打包的内容
    new CleanWebPackPlugin(["dist"]),

    // 配合 hot:true (好像不需要配置也行 devserver 发现我们没配置,会自动绑我们配置)
    // new webpack.HotModuleReplacementPlugin(),
  ],

  optimization: {
    // tree shaking 只支持es module 静态引入,
    //  development 默认没有开启 ,production 默认开启的
    //  但是像这种 import "@babel/polly-fill" ,tree-shaking发现没有导包的内容就会注掉那么这个引入的插件就没作用了。
    // 可以在package.json 中配置 "sideEffects": false or ["*.css","*.scss"]对所有模块进行tree shanking就可以解决了

    // 开发环境下 依然有(便于测试) 但是会有以下注释，
    /*! exports provided: add, minus */
    /*! exports used: add */

    // 生成环境就真的没有了，并且生产环境这个都不用配置默认帮我们配置好了，但是sideEffects 还是要写的
    usedExports: true,
  },
};
